package com.tanhua.server.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.RandomUtil;
import com.alibaba.fastjson.JSON;
import com.tanhua.autoconfig.templates.HuanXinTemplate;
import com.tanhua.commons.utils.Constants;
import com.tanhua.dubbo.api.*;
import com.tanhua.model.db.Question;
import com.tanhua.model.db.User;
import com.tanhua.model.db.UserInfo;
import com.tanhua.model.mongo.RecommendUser;
import com.tanhua.model.vo.ErrorResult;
import com.tanhua.model.vo.NearUserVo;
import com.tanhua.model.vo.PageResult;
import com.tanhua.model.vo.TodayBest;
import com.tanhua.server.exception.BusinessException;
import com.tanhua.server.interceptor.UserHolder;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @program: tanhua
 * @description:
 * @author: MR.peng
 * @create: 2022-03-11 13:30
 **/

@Service
public class TanhuaService {

    @DubboReference
    private RecommendUserApi recommendUserApi;

    @DubboReference
    private UserInfoApi userInfoApi;

    @DubboReference
    private QuestionApi questionApi;

    @Autowired
    private HuanXinTemplate huanXinTemplate;
    @Autowired
    private RedisTemplate<String, String> redisTemplate;


    @Autowired
    private MessageService messagesService;

    @DubboReference
    private VisitorsApi visitorsApi;

    @Value("${tanhua.default.recommend.users}")//在yml文件中我指定了
    private String recommendUser;

    @DubboReference
    private UserLikeApi userLikeApi;

    /*
    *今日佳人：
    *       根据touserId查询推荐用户，查询score最高的为用户即可，(RecommentUser)
    *       将RecommentUser转化为TodayBest的vo对象
    * */
    public TodayBest todayBEst() {
        //1.获取当前用户的id,查询条件
        Long touserId = UserHolder.getUserId();

        //2.调用api,根据touserId查询缘分值最高的数据
        RecommendUser recommendUser = recommendUserApi.findwithMaxScore(touserId);
        //3.TodayBest根据userId需要推荐用户的信息和缘分值
        UserInfo userInfo = userInfoApi.findUser(recommendUser.getUserId());
        //4.将RecommentUser转化为Today对象
        TodayBest vo = TodayBest.init(userInfo, recommendUser);
        return vo;
    }


    /*
    * 分页查询推荐的用户数据
    *   前端：分页的时候并不需要总数
    *   实质：调用API分页查询时，只需要数据列表就行了
    *
    * */
    public PageResult recommendation(Integer page,Integer pageSize){

        //1.获取当前用户Id,查询条件
        Long toUserId = UserHolder.getUserId();
        //2.调用API，根据userId分页查询数据列表 List<RecommentUser>
        List<RecommendUser> list  = recommendUserApi.findRecommtUsetList(toUserId,page,pageSize);
        //3.对于新用户没有推荐数据，那么构造一些默认数据
        if(CollUtil.isEmpty(list)){
            list = defaultList();
        }
        //4.将一个RecommentUser转化成一个TodayBest的vo对象，List<TodayBest>
        List<TodayBest> vos = new ArrayList<>();
        for (RecommendUser user : list) {
            UserInfo userInfo = userInfoApi.findUser(user.getUserId());
            TodayBest vo = TodayBest.init(userInfo, user);
            vos.add(vo);
        }
        //5.构造返回值PageResult
        return new PageResult(page,pageSize,0L,vos);

    }

    private List<RecommendUser> defaultList() {
        List<RecommendUser> list = new ArrayList<>();
        //构造默认推荐数据，企业中按照项目经理要求
        for (int i = 1; i <= 10; i++) {
            RecommendUser ru = new RecommendUser();
            ru.setUserId((long) i); //模拟推荐的用户id
            ru.setScore(95D); //模拟推荐的评分
            list.add(ru);
        }
        return list;
    }

    //今日佳人详情
    public TodayBest personalInfo(Long userId) {
        //1.用户信息
        UserInfo userInfo = userInfoApi.findUser(userId);
        //2.推荐数据(缘分值)
        Long toUserId = UserHolder.getUserId();
        RecommendUser user =  recommendUserApi.queryByUserId(userId,toUserId);
        //3.返回
        return TodayBest.init(userInfo,user);
    }

    //查看用户的陌生人问题
    public String strangerQuestions(Long userId) {
        Question question = questionApi.findByUserId(userId);
        return question == null ? "你喜欢java吗"  : question.getTxt();
    }

    //回复陌生人问题
    public void reply(Long userId, String reply) {
        //1.构造数据
        Map map = new HashMap();
        map.put("strangerQuestion",strangerQuestions(userId));
        map.put("reply",reply);
        //获取当前用户信息
        Long currentId = UserHolder.getUserId();
        UserInfo userInfo = userInfoApi.findUser(currentId);
        map.put("nickname",userInfo.getNickname());
        map.put("huanXinId","hx"+currentId);
        map.put("userId",currentId);
        //2.发送消息
        String msg = JSON.toJSONString(map);
        huanXinTemplate.sendMsg("hx"+userId,msg);//环信用户，消息内容
    }

    @DubboReference
    private  UserLocationApi userLocationApi;
    //搜索附近
    public List<NearUserVo> search(String gender, String distance) {
        //1.调用API查询附近的地理位置，返回附近的人的用户id集合
        Long userId = UserHolder.getUserId();
        List<Long> userIds = userLocationApi.searchNear(userId,distance); //当前用户id ，搜索距离
        //2.查询附近人的用户信息
        Map<Long, UserInfo> map = userInfoApi.findByIds(userIds);
        List<NearUserVo> vos = new ArrayList<>();
        //3.构造vo对象返回即可
        for (Long id : userIds) {
            //排除自己，当附近的人的用户id == 当前用户时，不在构建vo对象
            if(id == userId){
                continue;
            }
            UserInfo userInfo = map.get(id);
            //性别的筛选
            if(!gender.equals(userInfo.getGender())){
                continue;
            }
            NearUserVo vo = NearUserVo.init(userInfo);
            vos.add(vo);
        }
        return vos;
    }

    //探花-左滑右滑推荐数据
    public List<TodayBest> cards() {
        //调用API查询 排除相互喜欢和不喜欢的用户，限制推荐用户条数（10条）
        List<RecommendUser> users = recommendUserApi.findCardsUser(UserHolder.getUserId() ,10);
        //判断数据是否存在，如果不存在，，应该构造一些  假数据
        if (users.size() > 10) {//判次数
            throw new BusinessException(ErrorResult.countError());
        }
        if (CollUtil.isEmpty(users)) {
            users = new ArrayList<>();
            String[] userIds = recommendUser.split(",");
            for (String userid : userIds) {
                RecommendUser recommendUser = new RecommendUser();
                Long userId = Long.valueOf(userid);//转型

                recommendUser.setUserId(userId);//推荐的用户id
                recommendUser.setToUserId(UserHolder.getUserId());//用户id
                recommendUser.setScore(RandomUtil.randomDouble(50 ,90));//缘分值
                users.add(recommendUser);
            }
        }
        //查询用户详情
        List<Long> ids = CollUtil.getFieldValues(users ,"userId" ,Long.class);
        //优化
        Map<Long, UserInfo> map = userInfoApi.findByIds(ids);
        List<TodayBest> vos = new ArrayList<>();
        for (RecommendUser user : users) {
            UserInfo userInfo = map.get(user.getUserId());
            if (userInfo != null) {
                TodayBest vo = TodayBest.init(userInfo ,user);
                vos.add(vo);
            }
        }
        return vos;
    }
    //右滑喜欢
    public void love(Long likeUserId) {
        Boolean save = userLikeApi.saveOrUpdate(UserHolder.getUserId() ,likeUserId ,true);
        if (!save) {
            throw new BusinessException(ErrorResult.error());
        }
        //操作redis，写入不喜欢的数据，删除喜欢的数据 (喜欢的集合，不喜欢的集合)
        redisTemplate.opsForSet().add(Constants.USER_NOT_LIKE_KEY + UserHolder.getUserId() ,likeUserId.toString());
        redisTemplate.opsForSet().remove(Constants.USER_LIKE_KEY + UserHolder.getUserId() ,likeUserId.toString());
        //判断是否双向喜欢，
        if (isLike(likeUserId ,UserHolder.getUserId())) {

            //删除环信的好友关系和数据库好友关系
            messagesService.deleteFriend(UserHolder.getUserId() ,likeUserId);
        }
    }
    //左滑不喜欢
    public void unlove(Long likeUserId) {
        //调用API，保存喜欢数据(保存到MongoDB中)
        Boolean save = userLikeApi.saveOrUpdate(UserHolder.getUserId() ,likeUserId ,false);
        if (!save) {
            throw new BusinessException(ErrorResult.error());
        }
        //操作redis，写入喜欢的数据，删除不喜欢的数据 (喜欢的集合，不喜欢的集合)
        redisTemplate.opsForSet().remove(Constants.USER_NOT_LIKE_KEY + UserHolder.getUserId() ,likeUserId.toString());
        redisTemplate.opsForSet().add(Constants.USER_LIKE_KEY + UserHolder.getUserId() ,likeUserId.toString());
        //判断是否双向喜欢
        if (isLike(likeUserId ,UserHolder.getUserId())) {
            //4、添加好友
            messagesService.contacts(likeUserId);
            //huanXinTemplate.addContact("hx" + UserHolder.getId() ,"hx" + likeUserId);
        }
    }
    //判断是否双向喜欢
    public Boolean isLike(Long userId ,Long likeUserId) {
        String key = Constants.USER_LIKE_KEY + userId;
        return redisTemplate.opsForSet().isMember(key ,likeUserId.toString());//根据key查看集合中是否存在指定数据
    }
}
